package fsdownloadserver;
import FsInterfaces.IFileServer;
import FsInterfaces.ServerBandwidthBean;
import java.rmi.*;
import java.rmi.registry.*;
import java.util.ArrayList;
import java.util.Calendar;

public class DownloadServer extends java.rmi.server.UnicastRemoteObject implements FsInterfaces.IDownloadServer, ICallBack {

    private long timeOut = 10000; //10 secs.
    private int crashes=0; //represent number of crashed RMI calls.
    private int responses=0;

    private ServerBandwidthBean bestServerBandwidthBean;
    private ArrayList<ServerInfo> serverInfoList;

    private ServerInfoLoader serverInfoLoader = new ServerInfoLoader();
    Registry registry;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        DownloadServer downloadServer = new DownloadServer(args[0]);
    }

    public void setBandWidthCallback(ServerBandwidthBean serverBandwidthBean){
        responses++;
        if(serverBandwidthBean.getServerBandwidth()>bestServerBandwidthBean.getServerBandwidth())
            bestServerBandwidthBean = serverBandwidthBean;
    }

    public DownloadServer(String path) throws RemoteException{
        //there is only one downloadserver, wherefore we are always bindind it to localhost
        //in reality this would be a server on the net, but this is just for testing.

        serverInfoList = serverInfoLoader.LoadInfo(path);

        int port = 2221;
        String host = "localhost";
        String name = "DownloadServer";

        System.out.println("Starting Download Server: 'DownloadServer+' @ "+host+":"+port);
       //creating server and binding to registry
       try{
            registry = LocateRegistry.createRegistry(port);
            registry.rebind(name, this);
        }
        catch(RemoteException e){
            throw e;
        }
    }

    public ServerBandwidthBean RequestServer(String aTitle) throws RemoteException{
        crashes=0; //0 RMI calls have crashed as of so far.
        responses=0; //0 Sucessfull RMI calls have given return value from start;
        bestServerBandwidthBean = new ServerBandwidthBean(null, 0); // represents best time, none set when started

        long timeStamp = getTimeInMillis();

        for(ServerInfo serverInfo: serverInfoList){
            RmiCaller rmiCaller = new RmiCaller(serverInfo, this, aTitle);
            rmiCaller.run();
        }

        while(getTimeInMillis()<timeStamp+timeOut && responses+crashes<serverInfoList.size())
        {}//wait while time is less than timeout AND successfull RMI calls + Crashed RMI calls < total number of fileServers.

        if(bestServerBandwidthBean.getServerBandwidth()>0){
            System.out.println("Returning best server found @ "+bestServerBandwidthBean.getServerAddress()+" with "+bestServerBandwidthBean.getServerBandwidth()+" Kb/s");
        }
        else{
            System.out.println("Did not find any servers/no bandwidth available");
        }

        return bestServerBandwidthBean;
    }

    public void setCrashed(){
        crashes++;
    }

     private long getTimeInMillis(){
        return Calendar.getInstance().getTimeInMillis();
    }
}
